package com.powernode.shop.gateway.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.powernode.shop.gateway.constant.GatewayConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
 * @author ZHAOZHENYU
 * @since 2022/10/10
 */

@Configuration
public class LoginRouter {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 使用代码方式的路由做token的存储
     * 前端应用-------->gateway-------->auth-server
     * auth-server---token---->gateway---->redis----->前端应用
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        // 特定路由（oauth协议）来访问 oauth服务器
        return builder.routes()
                .route("auth-server-id", r -> r.path("/oauth/token")
                        .filters(f -> f.modifyResponseBody(String.class, String.class, (exchange, s) -> {
                            // s就是auth-server响应过来的值
                            JSONObject jsonObject = JSON.parseObject(s);
                            if (jsonObject.containsKey("access_token")) {
                                // 授权成功
                                String accessToken = jsonObject.getString("access_token");
                                Long expiresIn = jsonObject.getLong("expires_in");
                                // 存入redis 只用键验证 不用存value
                                redisTemplate.opsForValue().set(GatewayConstant.OAUTH_JWT_PREFIX + accessToken, "", Duration.ofSeconds(expiresIn));
                            }
                            return Mono.just(s);
                        })).uri("lb://auth-server"))
                .build();
    }

}
